home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2007 September / PCWSEP07.iso / Software / Linux / Linux Mint 3.0 Light / LinuxMint-3.0-Light.iso / casper / filesystem.squashfs / usr / lib / python2.5 / idlelib / AutoCompleteWindow.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2007-05-11  |  11.4 KB  |  338 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''
  5. An auto-completion window for IDLE, used by the AutoComplete extension
  6. '''
  7. from Tkinter import *
  8. from MultiCall import MC_SHIFT
  9. import AutoComplete
  10. HIDE_VIRTUAL_EVENT_NAME = '<<autocompletewindow-hide>>'
  11. HIDE_SEQUENCES = ('<FocusOut>', '<ButtonPress>')
  12. KEYPRESS_VIRTUAL_EVENT_NAME = '<<autocompletewindow-keypress>>'
  13. KEYPRESS_SEQUENCES = ('<Key>', '<Key-BackSpace>', '<Key-Return>', '<Key-Up>', '<Key-Down>', '<Key-Home>', '<Key-End>')
  14. KEYRELEASE_VIRTUAL_EVENT_NAME = '<<autocompletewindow-keyrelease>>'
  15. KEYRELEASE_SEQUENCE = '<KeyRelease>'
  16. LISTUPDATE_SEQUENCE = '<ButtonRelease>'
  17. WINCONFIG_SEQUENCE = '<Configure>'
  18. DOUBLECLICK_SEQUENCE = '<Double-ButtonRelease>'
  19.  
  20. class AutoCompleteWindow:
  21.     
  22.     def __init__(self, widget):
  23.         self.widget = widget
  24.         self.autocompletewindow = None
  25.         self.listbox = None
  26.         self.scrollbar = None
  27.         self.origselforeground = None
  28.         self.origselbackground = None
  29.         self.completions = None
  30.         self.morecompletions = None
  31.         self.mode = None
  32.         self.start = None
  33.         self.startindex = None
  34.         self.lasttypedstart = None
  35.         self.userwantswindow = None
  36.         self.hideid = None
  37.         self.keypressid = None
  38.         self.listupdateid = None
  39.         self.winconfigid = None
  40.         self.keyreleaseid = None
  41.         self.doubleclickid = None
  42.  
  43.     
  44.     def _change_start(self, newstart):
  45.         i = 0
  46.         while i < len(self.start) and i < len(newstart) and self.start[i] == newstart[i]:
  47.             i += 1
  48.         if i < len(self.start):
  49.             self.widget.delete('%s+%dc' % (self.startindex, i), '%s+%dc' % (self.startindex, len(self.start)))
  50.         
  51.         if i < len(newstart):
  52.             self.widget.insert('%s+%dc' % (self.startindex, i), newstart[i:])
  53.         
  54.         self.start = newstart
  55.  
  56.     
  57.     def _binary_search(self, s):
  58.         '''Find the first index in self.completions where completions[i] is
  59.         greater or equal to s, or the last index if there is no such
  60.         one.'''
  61.         i = 0
  62.         j = len(self.completions)
  63.         while j > i:
  64.             m = (i + j) // 2
  65.             if self.completions[m] >= s:
  66.                 j = m
  67.                 continue
  68.             i = m + 1
  69.         return min(i, len(self.completions) - 1)
  70.  
  71.     
  72.     def _complete_string(self, s):
  73.         '''Assuming that s is the prefix of a string in self.completions,
  74.         return the longest string which is a prefix of all the strings which
  75.         s is a prefix of them. If s is not a prefix of a string, return s.'''
  76.         first = self._binary_search(s)
  77.         if self.completions[first][:len(s)] != s:
  78.             return s
  79.         
  80.         i = first + 1
  81.         j = len(self.completions)
  82.         while j > i:
  83.             m = (i + j) // 2
  84.             if self.completions[m][:len(s)] != s:
  85.                 j = m
  86.                 continue
  87.             i = m + 1
  88.         last = i - 1
  89.         i = len(s)
  90.         while len(self.completions[first]) > i and len(self.completions[last]) > i and self.completions[first][i] == self.completions[last][i]:
  91.             i += 1
  92.         return self.completions[first][:i]
  93.  
  94.     
  95.     def _selection_changed(self):
  96.         '''Should be called when the selection of the Listbox has changed.
  97.         Updates the Listbox display and calls _change_start.'''
  98.         cursel = int(self.listbox.curselection()[0])
  99.         self.listbox.see(cursel)
  100.         lts = self.lasttypedstart
  101.         selstart = self.completions[cursel]
  102.         if self._binary_search(lts) == cursel:
  103.             newstart = lts
  104.         else:
  105.             i = 0
  106.             while i < len(lts) and i < len(selstart) and lts[i] == selstart[i]:
  107.                 i += 1
  108.             while cursel > 0 and selstart[:i] <= self.completions[cursel - 1]:
  109.                 i += 1
  110.             newstart = selstart[:i]
  111.         self._change_start(newstart)
  112.         if self.completions[cursel][:len(self.start)] == self.start:
  113.             self.listbox.configure(selectbackground = self.origselbackground, selectforeground = self.origselforeground)
  114.         else:
  115.             self.listbox.configure(selectbackground = self.listbox.cget('bg'), selectforeground = self.listbox.cget('fg'))
  116.             if self.morecompletions:
  117.                 self.completions = self.morecompletions
  118.                 self.morecompletions = None
  119.                 self.listbox.delete(0, END)
  120.                 for item in self.completions:
  121.                     self.listbox.insert(END, item)
  122.                 
  123.                 self.listbox.select_set(self._binary_search(self.start))
  124.                 self._selection_changed()
  125.             
  126.  
  127.     
  128.     def show_window(self, comp_lists, index, complete, mode, userWantsWin):
  129.         """Show the autocomplete list, bind events.
  130.         If complete is True, complete the text, and if there is exactly one
  131.         matching completion, don't open a list."""
  132.         (self.completions, self.morecompletions) = comp_lists
  133.         self.mode = mode
  134.         self.startindex = self.widget.index(index)
  135.         self.start = self.widget.get(self.startindex, 'insert')
  136.         if complete:
  137.             completed = self._complete_string(self.start)
  138.             self._change_start(completed)
  139.             i = self._binary_search(completed)
  140.             if self.completions[i] == completed:
  141.                 pass
  142.             None if i == len(self.completions) - 1 or self.completions[i + 1][:len(completed)] != completed else self.completions[i + 1][:len(completed)] != completed
  143.         
  144.         self.userwantswindow = userWantsWin
  145.         self.lasttypedstart = self.start
  146.         self.autocompletewindow = acw = Toplevel(self.widget)
  147.         acw.wm_geometry('+10000+10000')
  148.         acw.wm_overrideredirect(1)
  149.         
  150.         try:
  151.             acw.tk.call('::tk::unsupported::MacWindowStyle', 'style', acw._w, 'help', 'noActivates')
  152.         except TclError:
  153.             pass
  154.  
  155.         self.scrollbar = scrollbar = Scrollbar(acw, orient = VERTICAL)
  156.         self.listbox = listbox = Listbox(acw, yscrollcommand = scrollbar.set, exportselection = False, bg = 'white')
  157.         for item in self.completions:
  158.             listbox.insert(END, item)
  159.         
  160.         self.origselforeground = listbox.cget('selectforeground')
  161.         self.origselbackground = listbox.cget('selectbackground')
  162.         scrollbar.config(command = listbox.yview)
  163.         scrollbar.pack(side = RIGHT, fill = Y)
  164.         listbox.pack(side = LEFT, fill = BOTH, expand = True)
  165.         self.listbox.select_set(self._binary_search(self.start))
  166.         self._selection_changed()
  167.         self.hideid = self.widget.bind(HIDE_VIRTUAL_EVENT_NAME, self.hide_event)
  168.         for seq in HIDE_SEQUENCES:
  169.             self.widget.event_add(HIDE_VIRTUAL_EVENT_NAME, seq)
  170.         
  171.         self.keypressid = self.widget.bind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypress_event)
  172.         for seq in KEYPRESS_SEQUENCES:
  173.             self.widget.event_add(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
  174.         
  175.         self.keyreleaseid = self.widget.bind(KEYRELEASE_VIRTUAL_EVENT_NAME, self.keyrelease_event)
  176.         self.widget.event_add(KEYRELEASE_VIRTUAL_EVENT_NAME, KEYRELEASE_SEQUENCE)
  177.         self.listupdateid = listbox.bind(LISTUPDATE_SEQUENCE, self.listupdate_event)
  178.         self.winconfigid = acw.bind(WINCONFIG_SEQUENCE, self.winconfig_event)
  179.         self.doubleclickid = listbox.bind(DOUBLECLICK_SEQUENCE, self.doubleclick_event)
  180.  
  181.     
  182.     def winconfig_event(self, event):
  183.         if not self.is_active():
  184.             return None
  185.         
  186.         acw = self.autocompletewindow
  187.         self.widget.see(self.startindex)
  188.         (x, y, cx, cy) = self.widget.bbox(self.startindex)
  189.         acw.wm_geometry('+%d+%d' % (x + self.widget.winfo_rootx(), y + self.widget.winfo_rooty() - acw.winfo_height()))
  190.  
  191.     
  192.     def hide_event(self, event):
  193.         if not self.is_active():
  194.             return None
  195.         
  196.         self.hide_window()
  197.  
  198.     
  199.     def listupdate_event(self, event):
  200.         if not self.is_active():
  201.             return None
  202.         
  203.         self.userwantswindow = True
  204.         self._selection_changed()
  205.  
  206.     
  207.     def doubleclick_event(self, event):
  208.         cursel = int(self.listbox.curselection()[0])
  209.         self._change_start(self.completions[cursel])
  210.         self.hide_window()
  211.  
  212.     
  213.     def keypress_event(self, event):
  214.         if not self.is_active():
  215.             return None
  216.         
  217.         keysym = event.keysym
  218.         if hasattr(event, 'mc_state'):
  219.             state = event.mc_state
  220.         else:
  221.             state = 0
  222.         if (len(keysym) == 1 and keysym in ('underscore', 'BackSpace') or self.mode == AutoComplete.COMPLETE_FILES or keysym in ('period', 'minus')) and not (state & ~MC_SHIFT):
  223.             if len(keysym) == 1:
  224.                 self._change_start(self.start + keysym)
  225.             elif keysym == 'underscore':
  226.                 self._change_start(self.start + '_')
  227.             elif keysym == 'period':
  228.                 self._change_start(self.start + '.')
  229.             elif keysym == 'minus':
  230.                 self._change_start(self.start + '-')
  231.             elif len(self.start) == 0:
  232.                 self.hide_window()
  233.                 return None
  234.             
  235.             self._change_start(self.start[:-1])
  236.             self.lasttypedstart = self.start
  237.             self.listbox.select_clear(0, int(self.listbox.curselection()[0]))
  238.             self.listbox.select_set(self._binary_search(self.start))
  239.             self._selection_changed()
  240.             return 'break'
  241.         elif keysym == 'Return' and not state:
  242.             cursel = int(self.listbox.curselection()[0])
  243.             if self.completions[cursel][:len(self.start)] == self.start or self.userwantswindow:
  244.                 self._change_start(self.completions[cursel])
  245.                 self.hide_window()
  246.                 return 'break'
  247.             else:
  248.                 self.hide_window()
  249.                 return None
  250.         elif not self.mode == AutoComplete.COMPLETE_ATTRIBUTES or keysym in ('period', 'space', 'parenleft', 'parenright', 'bracketleft', 'bracketright'):
  251.             if (self.mode == AutoComplete.COMPLETE_FILES or keysym in ('slash', 'backslash', 'quotedbl', 'apostrophe')) and not (state & ~MC_SHIFT):
  252.                 cursel = int(self.listbox.curselection()[0])
  253.                 if self.completions[cursel][:len(self.start)] == self.start:
  254.                     if self.mode == AutoComplete.COMPLETE_ATTRIBUTES or self.start:
  255.                         self._change_start(self.completions[cursel])
  256.                     
  257.                 self.hide_window()
  258.                 return None
  259.             elif keysym in ('Home', 'End', 'Prior', 'Next', 'Up', 'Down') and not state:
  260.                 self.userwantswindow = True
  261.                 cursel = int(self.listbox.curselection()[0])
  262.                 if keysym == 'Home':
  263.                     newsel = 0
  264.                 elif keysym == 'End':
  265.                     newsel = len(self.completions) - 1
  266.                 elif keysym in ('Prior', 'Next'):
  267.                     jump = self.listbox.nearest(self.listbox.winfo_height()) - self.listbox.nearest(0)
  268.                     if keysym == 'Prior':
  269.                         newsel = max(0, cursel - jump)
  270.                     elif not keysym == 'Next':
  271.                         raise AssertionError
  272.                     newsel = min(len(self.completions) - 1, cursel + jump)
  273.                 elif keysym == 'Up':
  274.                     newsel = max(0, cursel - 1)
  275.                 elif not keysym == 'Down':
  276.                     raise AssertionError
  277.                 newsel = min(len(self.completions) - 1, cursel + 1)
  278.                 self.listbox.select_clear(cursel)
  279.                 self.listbox.select_set(newsel)
  280.                 self._selection_changed()
  281.                 return 'break'
  282.             elif keysym == 'Tab' and not state:
  283.                 self.userwantswindow = True
  284.                 return None
  285.             elif []([], [ keysym.find(s) != -1 for s in ('Shift', 'Control', 'Alt', 'Meta', 'Command', 'Option') ]):
  286.                 return None
  287.             else:
  288.                 self.hide_window()
  289.                 return None
  290.  
  291.     
  292.     def keyrelease_event(self, event):
  293.         if not self.is_active():
  294.             return None
  295.         
  296.         if self.widget.index('insert') != self.widget.index('%s+%dc' % (self.startindex, len(self.start))):
  297.             self.hide_window()
  298.         
  299.  
  300.     
  301.     def is_active(self):
  302.         return self.autocompletewindow is not None
  303.  
  304.     
  305.     def complete(self):
  306.         self._change_start(self._complete_string(self.start))
  307.  
  308.     
  309.     def hide_window(self):
  310.         if not self.is_active():
  311.             return None
  312.         
  313.         for seq in HIDE_SEQUENCES:
  314.             self.widget.event_delete(HIDE_VIRTUAL_EVENT_NAME, seq)
  315.         
  316.         self.widget.unbind(HIDE_VIRTUAL_EVENT_NAME, self.hideid)
  317.         self.hideid = None
  318.         for seq in KEYPRESS_SEQUENCES:
  319.             self.widget.event_delete(KEYPRESS_VIRTUAL_EVENT_NAME, seq)
  320.         
  321.         self.widget.unbind(KEYPRESS_VIRTUAL_EVENT_NAME, self.keypressid)
  322.         self.keypressid = None
  323.         self.widget.event_delete(KEYRELEASE_VIRTUAL_EVENT_NAME, KEYRELEASE_SEQUENCE)
  324.         self.widget.unbind(KEYRELEASE_VIRTUAL_EVENT_NAME, self.keyreleaseid)
  325.         self.keyreleaseid = None
  326.         self.listbox.unbind(LISTUPDATE_SEQUENCE, self.listupdateid)
  327.         self.listupdateid = None
  328.         self.autocompletewindow.unbind(WINCONFIG_SEQUENCE, self.winconfigid)
  329.         self.winconfigid = None
  330.         self.scrollbar.destroy()
  331.         self.scrollbar = None
  332.         self.listbox.destroy()
  333.         self.listbox = None
  334.         self.autocompletewindow.destroy()
  335.         self.autocompletewindow = None
  336.  
  337.  
  338.